package cool.mtc.io.upload.read.config;

import cool.mtc.core.exception.StartupException;
import cool.mtc.io.upload.UploadProperties;
import cool.mtc.io.upload.read.interceptor.StaticResourceInterceptor;
import cool.mtc.io.upload.read.interceptor.StaticResourceInterceptorContext;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author 明河
 */
@Slf4j
@Configuration
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class StaticResourceReadConfigurer implements WebMvcConfigurer {
    private final UploadProperties uploadProperties;
    private final StaticResourceInterceptorContext staticResourceInterceptorContext;

    @SneakyThrows
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        int order = 1;
        for (UploadProperties.Type type : uploadProperties.getTypes()) {
            UploadProperties.Read read = type.getRead();
            StaticResourceInterceptor interceptor = staticResourceInterceptorContext.getInterceptor(read.getPermission());
            if (null == interceptor) {
                String errMsg = String.format("Bean[%s]未定义", read.getPermission().getInterceptorBeanName());
                log.error(errMsg);
                throw new StartupException(errMsg);
            }
            registry.addInterceptor(interceptor)
                    .addPathPatterns(read.getRequestPathPatterns().toArray(new String[0]))
                    .order(order++);
        }
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        Map<String, List<String>> resourcesMap = new HashMap<>();
        for (UploadProperties.Type type : uploadProperties.getTypes()) {
            UploadProperties.Read read = type.getRead();

            List<String> locationList = new ArrayList<>();
            String location = type.getInusePath(uploadProperties);
            locationList.add(location);

            read.getRequestPathPatterns().forEach(path -> {
                if (resourcesMap.containsKey(path)) {
                    resourcesMap.get(path).addAll(locationList);
                } else {
                    resourcesMap.put(path, locationList);
                }
            });
        }

        resourcesMap.forEach((path, locationList) -> {
            registry.addResourceHandler(path)
                    .addResourceLocations(locationList.toArray(new String[0]));
        });
    }
}
